using AutoMapper;
using B.S.NewMedical.Api.Read.Application.Command.ContentManagement.VisitRecord;
using B.S.NewMedical.Api.Read.DTOS.VisitRecord;
using B.S.NewMedical.Domain.Hospital;
using B.S.NewMedical.ErrorCode;
using B.S.NewMedical.Infrastructure.Interface;
using MediatR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace B.S.NewMedical.Api.Read.Application.Handler.ContentManagement.VisitRecord
{
    /// <summary>
    /// 根据患者ID获取就诊记录列表处理器
    /// </summary>
    public class GetVisitRecordsByPatientIdHandler : IRequestHandler<GetVisitRecordsByPatientIdCommand, ApiPageing<List<VisitRecordDto>>>
    {
        private readonly IBaseRepository<VisitRecordModel> _visitRecordRepository;
        private readonly ILogger<GetVisitRecordsByPatientIdHandler> _logger;
        private readonly IMapper _mapper;

        public GetVisitRecordsByPatientIdHandler(
            IBaseRepository<VisitRecordModel> visitRecordRepository,
            ILogger<GetVisitRecordsByPatientIdHandler> logger,
            IMapper mapper)
        {
            _visitRecordRepository = visitRecordRepository ?? throw new ArgumentNullException(nameof(visitRecordRepository));
            _logger = logger ?? throw new ArgumentNullException(nameof(logger));
            _mapper = mapper ?? throw new ArgumentNullException(nameof(mapper));
        }

        /// <summary>
        /// 处理根据患者ID获取就诊记录列表请求
        /// </summary>
        public async Task<ApiPageing<List<VisitRecordDto>>> Handle(GetVisitRecordsByPatientIdCommand request, CancellationToken cancellationToken)
        {
            try
            {
                _logger.LogInformation("开始获取患者就诊记录列表，患者ID：{PatientId}，查询条件：{@QueryDto}", request.PatientId, request.QueryDto);

                var query = _visitRecordRepository.GetAll().Where(v => !v.IsDeleted);

                // 按患者ID筛选
                query = query.Where(v => v.PatientId == request.PatientId);

                // 应用查询条件
                if (request.QueryDto.VisitTypeId.HasValue)
                {
                    query = query.Where(v => v.VisitTypeId == request.QueryDto.VisitTypeId);
                }

                if (request.QueryDto.VisitTimeStart.HasValue)
                {
                    query = query.Where(v => v.VisitTime >= request.QueryDto.VisitTimeStart);
                }

                if (request.QueryDto.VisitTimeEnd.HasValue)
                {
                    query = query.Where(v => v.VisitTime <= request.QueryDto.VisitTimeEnd);
                }

                if (!string.IsNullOrWhiteSpace(request.QueryDto.VisitLocation))
                {
                    query = query.Where(v => v.VisitLocation != null && v.VisitLocation.Contains(request.QueryDto.VisitLocation));
                }

                // 排序：按就诊时间降序（最新的在前面）
                query = query.OrderByDescending(v => v.VisitTime).ThenByDescending(v => v.CreateTime);

                // 计算总数
                var totalCount = await query.CountAsync(cancellationToken);

                // 分页
                var items = await query
                    .Skip((request.QueryDto.PageIndex - 1) * request.QueryDto.PageSize)
                    .Take(request.QueryDto.PageSize)
                    .ToListAsync(cancellationToken);

                // 映射到DTO
                var visitRecordDtos = _mapper.Map<List<VisitRecordDto>>(items);

                _logger.LogInformation("成功获取患者就诊记录列表，患者ID：{PatientId}，总数：{TotalCount}", request.PatientId, totalCount);

                return new ApiPageing<List<VisitRecordDto>>
                {
                    Code = ApiEnum.Success,
                    Msg = "获取就诊记录列表成功",
                    Data = visitRecordDtos,
                    TotaCount = totalCount,
                    TotaPage = (int)Math.Ceiling((double)totalCount / request.QueryDto.PageSize)
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取患者就诊记录列表时发生异常，患者ID：{PatientId}", request.PatientId);
                return new ApiPageing<List<VisitRecordDto>>
                {
                    Code = ApiEnum.Error,
                    Msg = "获取就诊记录列表失败：" + ex.Message,
                    Data = new List<VisitRecordDto>()
                };
            }
        }
    }
}